#include <EIKENV.H>
#include <COEUTILS.H>
#include "CImageHandler.h"

CImageHandler::CImageHandler(RFs& aFs)
	: iFs(aFs), CActive(CActive::EPriorityStandard)
{
	iBitmap = new(ELeave) CFbsBitmap();
	iBitmap->Create(TSize(0,0), EColor64K);

	iMaskBitmap = new(ELeave) CFbsBitmap();
	iMaskBitmap->Create(TSize(0,0), EGray2);

	iCallback = this;
	ConstructL();
}

void CImageHandler::ConstructL()
	{
	CActiveScheduler::Add(this);
	iLoadUtil = NULL;
	iLoadUtil2 = NULL;
	}

CImageHandler::~CImageHandler()
	{
	delete iBitmap;
	delete iMaskBitmap;
	delete iLoadUtil;
	delete iLoadUtil2;

	}
	
void CImageHandler::Test()
{
	SetActive();
}	

void CImageHandler::CopyBitmap(CFbsBitmap* newBitmap)
{
	//create the bitmap with the same size and displaymode as the source
	if(newBitmap->Handle() == 0)
		newBitmap->Create(iBitmap->SizeInPixels(), iBitmap->DisplayMode());

	//get the gc of this new bitmap
	CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL(newBitmap);
	CFbsBitGc* bitmapGc;
	bitmapDevice->CreateContext(bitmapGc);
	//the copy happens here
	bitmapGc->BitBlt(TPoint(0,0), iBitmap, TRect(iBitmap->SizeInPixels()));

	//destroy
	delete bitmapDevice;
	delete bitmapGc;
}

void CImageHandler::CopyMaskBitmap(CFbsBitmap* newBitmap, TRgb bkcolor)
{
	//create the bitmap with the same size and displaymode as the source
	if(newBitmap->Handle() == 0)
		newBitmap->Create(iBitmap->SizeInPixels(), iMaskBitmap->DisplayMode());

	//get the gc of this new bitmap
	CFbsBitmapDevice* bitmapDevice = CFbsBitmapDevice::NewL(newBitmap);
	CFbsBitGc* bitmapGc;
	bitmapDevice->CreateContext(bitmapGc);
		bitmapGc->SetBrushColor(bkcolor);
		bitmapGc->Clear();
	//the copy happens here
	bitmapGc->BitBlt(TPoint(0,0), iMaskBitmap, TRect(iMaskBitmap->SizeInPixels()));

	//destroy
	delete bitmapDevice;
	delete bitmapGc;
}

void CImageHandler::FastImageInfo(const TDesC& aFileName, TSize& size)
{
	__ASSERT_ALWAYS(!IsActive(),User::Invariant());
	if(!ConeUtils::FileExists(aFileName))
	{
		//create a empty bitmap
		size.iWidth = 50;
		size.iHeight = 20;
		return;
	}
	
	// create a CImageDecoder to read the specified file
	delete iLoadUtil;
	iLoadUtil = NULL;
	iLoadUtil = CImageDecoder::FileNewL(iFs, aFileName);
	// store the frame information and frame count
	iFrameInfo = iLoadUtil->FrameInfo(0);
	iFrameCount = iLoadUtil->FrameCount();
	// resize the destination bitmap to fit the required size
	TRect bitmapSize = iFrameInfo.iFrameCoordsInPixels;
	size.iWidth = bitmapSize.Width();
	size.iHeight = bitmapSize.Height();
}

void CImageHandler::FastImageInfo(TPtrC8* bufptr, TSize& size)
{
	__ASSERT_ALWAYS(!IsActive(),User::Invariant());
	// create a CImageDecoder to read the specified file
	if(iLoadUtil2 == NULL)
		iLoadUtil2 = CBufferedImageDecoder::NewL(iFs);
	else
		iLoadUtil2->Reset();

	iLoadUtil2->OpenL(*bufptr);
	// store the frame information and frame count
	iFrameCount = iLoadUtil2->FrameCount();
	int selected = 0;

	iFrameInfo = iLoadUtil2->FrameInfo(selected);
	// resize the destination bitmap to fit the required size
	TRect bitmapSize = iFrameInfo.iFrameCoordsInPixels;

	size.iWidth = bitmapSize.Width();
	size.iHeight = bitmapSize.Height();
}

//just load an image file
void CImageHandler::LoadFileL(const TDesC& aFileName, TInt aSelectedFrame)
	{
	__ASSERT_ALWAYS(!IsActive(),User::Invariant());
	if(!ConeUtils::FileExists(aFileName))
	{
		if(iCallback)
			iCallback->ImageOperationComplete(1);		
		return;
	}	
	
	// create a CImageDecoder to read the specified file
	delete iLoadUtil;
	iLoadUtil = NULL;
	iLoadUtil = CImageDecoder::FileNewL(iFs, aFileName);
	// store the frame information and frame count
	iFrameInfo = iLoadUtil->FrameInfo(aSelectedFrame);
	iFrameCount = iLoadUtil->FrameCount();
	// resize the destination bitmap to fit the required size
	TRect bitmapSize = iFrameInfo.iFrameCoordsInPixels;
	
	iBitmap->Resize(bitmapSize.Size());
	//iBitmap.Resize(iFrameInfo.iOverallSizeInPixels);
	// start reading the bitmap: RunL called when complete
	//modified by william
//	iLoadUtil->Convert(&iStatus, *iBitmap, aSelectedFrame);
	if(aSelectedFrame > 0)//ani gif
	{
		iMaskBitmap->Resize(bitmapSize.Size());
		iLoadUtil->Convert(&iStatus, *iBitmap, *iMaskBitmap, aSelectedFrame);
	}
	else
	{
		//对于静态gif，可能有透明区域
		bool bTransparent = (iFrameInfo.iFlags & TFrameInfo::ETransparencyPossible) != 0;
		if(!bTransparent)
			iLoadUtil->Convert(&iStatus, *iBitmap, aSelectedFrame);
		else
		{
			iMaskBitmap->Resize(bitmapSize.Size());
			iLoadUtil->Convert(&iStatus, *iBitmap, *iMaskBitmap, aSelectedFrame);
		}
	}
	
	
	
	SetActive();
	}

//weidong yu
void CImageHandler::LoadBuffer(RFile file, long pos, long size, TInt aSelectedFrame)
	{
	__ASSERT_ALWAYS(!IsActive(),User::Invariant());
	// create a CImageDecoder to read the specified file
	if(iLoadUtil2 == NULL)
		iLoadUtil2 = CBufferedImageDecoder::NewL(iFs);
	else
		iLoadUtil2->Reset();
	/*
	delete iLoadUtil2;
	iLoadUtil2 = NULL;
	iLoadUtil2 = CBufferedImageDecoder::NewL(iFs);
		*/

	///TUint8* tbuf = new( ELeave )TUint8[ size ];
	TUint8* buf = new TUint8[size];

	TPtr8* ptr = new TPtr8 ( buf, size, size ); 

	int pos2 = pos;
	TBuf<10> temp;
	temp.Num(pos2);
	CEikonEnv::Static()->InfoWinL(_L("test"), temp);		
	
	file.Seek(ESeekStart, pos2);
	User::LeaveIfError( file.Read( *ptr , size ));

	iLoadUtil2->OpenL(*ptr);
	// store the frame information and frame count
	iFrameCount = iLoadUtil2->FrameCount();
	int selected = (aSelectedFrame >= iFrameCount)? 0 : aSelectedFrame;

	iFrameInfo = iLoadUtil2->FrameInfo(selected);
	// resize the destination bitmap to fit the required size
	TRect bitmapSize = iFrameInfo.iFrameCoordsInPixels;

	iBitmap->Resize(bitmapSize.Size());

	// start reading the bitmap: RunL called when complete
	iLoadUtil2->Convert(&iStatus, *iBitmap, selected);

	SetActive();
	delete []ptr;
	delete []buf;
	}

//modified by william
void CImageHandler::LoadBuffer(TPtrC8* bufptr, TInt aSelectedFrame)
{
	__ASSERT_ALWAYS(!IsActive(),User::Invariant());
	// create a CImageDecoder to read the specified file
	if(iLoadUtil2 == NULL)
		iLoadUtil2 = CBufferedImageDecoder::NewL(iFs);
	else
		iLoadUtil2->Reset();

	iLoadUtil2->OpenL(*bufptr);
	// store the frame information and frame count
	iFrameCount = iLoadUtil2->FrameCount();
	int selected = (aSelectedFrame >= iFrameCount)? 0 : aSelectedFrame;

	iFrameInfo = iLoadUtil2->FrameInfo(selected);
	// resize the destination bitmap to fit the required size
	TRect bitmapSize = iFrameInfo.iFrameCoordsInPixels;

	iBitmap->Resize(bitmapSize.Size());

	// start reading the bitmap: RunL called when complete
//	iLoadUtil2->Convert(&iStatus, *iBitmap, selected);
	if(selected > 0)//ani gif
	{
		iMaskBitmap->Resize(bitmapSize.Size());
		iLoadUtil2->Convert(&iStatus, *iBitmap, *iMaskBitmap, selected);
	}
	else
	{
		//对于静态gif，可能有透明区域
		bool bTransparent = (iFrameInfo.iFlags & TFrameInfo::ETransparencyPossible) != 0;
		if(!bTransparent)
			iLoadUtil2->Convert(&iStatus, *iBitmap, selected);
		else
		{
			iMaskBitmap->Resize(bitmapSize.Size());
			iLoadUtil2->Convert(&iStatus, *iBitmap, *iMaskBitmap, selected);
		}
	}
	

	SetActive();
}
	
void CImageHandler::RunL()
	{
	// Operation complete, call back caller
	if(iCallback)
	iCallback->ImageOperationComplete(iStatus.Int());
	}
	 
void CImageHandler::DoCancel()
	{
	// Cancel everything possible
	if (iLoadUtil) iLoadUtil->Cancel();
	if (iLoadUtil2) iLoadUtil2->Cancel();
	}

void CImageHandler::ImageOperationComplete(TInt aError)
{
}

CFbsBitmap* CImageHandler::Bitmap()
{
	return iBitmap;
}

CFbsBitmap* CImageHandler::MaskBitmap()
{
	return iMaskBitmap;
}
	    
void CImageHandler::SetCallback(MImageHandlerCallback *aCallback)
{
	iCallback = aCallback;
}
